﻿using System;
using System.Text;

namespace DotNetStar.OpenSDK.WeChat.Pay
{
    using System.Security.Cryptography;
    using Payment;
    /// <summary>
    /// 微信支付签名算法。
    /// </summary>
    /// <seealso cref="ISignatureHasher" />
    public class WeChatPaySignatureHasher : ISignatureHasher
    {
        private string key;

        /// <summary>
        /// 使用密钥初始化 <see cref="WeChatPaySignatureHasher"/> 类的新实例。
        /// </summary>
        /// <param name="key">商户密钥。</param>
        public WeChatPaySignatureHasher(string key) => this.key = key;

        /// <summary>
        /// 为指定的对象生成签名。
        /// </summary>
        /// <param name="model">要生成签名的对象。</param>
        /// <returns>
        /// 签名字符串。
        /// </returns>
        public virtual string GenerateSignature(object model)
        {
            var kv = new KeyValueCollection(model);
            var keyValueString = kv.ToString();

            var signStampStr = $"{keyValueString}&key={key}";

            var buffer = Encoding.UTF8.GetBytes(signStampStr);

            switch (kv["sign_type"].ToString().ToLower())
            {
                case "md5":
                    return BitConverter.ToString(MD5.Create().ComputeHash(buffer)).Replace("-", string.Empty).ToUpper();
                default:
                    return BitConverter.ToString(SHA256.Create().ComputeHash(buffer)).Replace("-", string.Empty).ToUpper();
            }
        }
        /// <summary>
        /// 校验指定的签名是与指定的对象生成的签名所匹配。
        /// </summary>
        /// <param name="model">生成签名的对象。</param>
        /// <param name="hashedSign">要验证的签名字符串。</param>
        /// <returns>
        /// 若匹配，则为 <c>true</c>；否则为 <c>false</c>。
        /// </returns>
        public virtual bool ValidateSignature(object model, string hashedSign) => GenerateSignature(model) == hashedSign;
    }
}
